package com.zym.init.core.plugin.storage.engine;

import com.zym.init.core.exception.ServiceException;
import io.minio.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.Map;

/**
 * Minio存储引擎
 */
@Slf4j
public class MinioStorage {

    /**
     * 桶名称
     */
    private final String bucketName;

    /**
     * Minio客户端
     */
    private final MinioClient client;

    public MinioStorage(Map<String, String> config) {
        // ip地址 https://127.0.0.1:9000
        String endpoint = config.get("endpoint");
        //用户名
        String accessKey = config.get("access_key");
        // 密码
        String secretKey = config.get("secret_key");
        // 区域
        String region = config.get("region");
        // 桶名称
        this.bucketName = config.get("bucket_name");
        // 创建Minio客户端
        this.client = MinioClient.builder()
                .endpoint(endpoint)
                .region(region)
                .credentials(accessKey, secretKey)
                .build();
    }

    /**
     * 上传文件
     *
     * @param multipartFile 文件
     * @param saveDir       保存路径 {username}/{datetime} or {datetime}
     * @param fileName      文件名称 name.jpg
     */
    public void upload(MultipartFile multipartFile, String saveDir, String fileName) {
        // 自动创建桶
        // createBucket();
        try {
            // 构建上传参数
            PutObjectArgs args = PutObjectArgs.builder()
                    // 桶名称
                    .bucket(bucketName)
                    // 完整路径 + 文件名
                    .object(saveDir + "/" + fileName)
                    // 文件类型
                    .contentType(multipartFile.getContentType())
                    // 文件流
                    .stream(multipartFile.getInputStream(), multipartFile.getSize(), -1)
                    .build();
            // 上传文件
            client.putObject(args);
        } catch (Exception e) {
            throw new ServiceException("上传文件失败：" + e);
        }
    }

    /**
     * 自动创建桶
     */
    private void createBucket() {
        try {
            boolean bucketExists = client.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            // 检查桶是否存在
            if (!bucketExists) {
                // 不存在，则创建桶
                client.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }
        } catch (Exception e) {
            throw new ServiceException("创建桶失败：" + e);
        }
    }

    /**
     * 删除
     *
     * @param paths 路径
     */
    public void delete(List<String> paths) {
        for (String path : paths) {
            try {
                // 构建参数
                RemoveObjectArgs args = RemoveObjectArgs.builder()
                        // 桶名称
                        .bucket(bucketName)
                        // 完整路径 + 文件名
                        .object(path)
                        .build();
                // 删除文件
                client.removeObject(args);
            } catch (Exception e) {
                log.error("删除文件失败：{}", path, e);
            }
        }
    }

}
